package client;

import communicate_interface.ClientInterface;
import communicate_interface.ServerInterface;
import constant.Constant;
import gui.ConfirmConflictDialog;
import gui.ContentMain;
import gui.DisplayPanel;
import gui.StatusBar;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.AccessException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import server.TodoItem;

public class ClientControl {
    
    private ServerInterface server ;
    private ArrayList<TodoItem> todoList = new ArrayList<TodoItem>();
    public static ClientControl instance = new ClientControl();
    private ClientInterface client;
    
    private ClientControl(){
        try {
            Registry registry = LocateRegistry.getRegistry("localhost");
            server = (ServerInterface) registry.lookup("Server");
            
            client = (ClientInterface) UnicastRemoteObject.exportObject(new Client(), 0);
        } catch (NotBoundException ex) {
            ex.printStackTrace();
        } catch (AccessException ex) {
            ex.printStackTrace();
        } catch (RemoteException ex) {
            ex.printStackTrace();
        }
        
//        try {
//            todoList = (ArrayList<TodoItem>)getListServer();
//        } catch (RemoteException ex) {
//            Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
//        }
    };
    
    public void updateList(TodoItem item) throws RemoteException {      
        boolean succeed = false;
        int answer;

        while (!succeed) {
            System.out.println("item id = "+item.getId());
            TodoItem updateItem = server.updateTodo(item, client);
            if (updateItem != null) {
                if (item.getId() != -1) {
                    todoList.add(updateItem);
                } else {
                    item.setId(updateItem.getId());
                }
                succeed = true;
            } else {
                TodoItem newItem = server.getTodo(item.getId());

                if (newItem != null) {
                    answer = (new ConfirmConflictDialog(item,newItem,(JFrame) SwingUtilities.getRoot(ContentMain.instance),true)).showDialog();

                    if (answer==Constant.ERASE_BUT) {
                        item.setVersion(newItem.getVersion());
                    } else {
                        todoList.add(newItem);
                        succeed = true;
                    }
                } else {
                    Object[] options = { "Recreate", "Ignore" };
                    answer=JOptionPane.showOptionDialog(SwingUtilities.getRoot(ContentMain.instance), 
                            "This item already delete by other user. Do you want to recreate it or ignore change?", 
                            "Item already deleted",JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE,
                    null, options, options[0]);
                    if (answer==JOptionPane.OK_OPTION) {
                        item.setId(-1);
                    } else {
                        todoList.remove(item);
                        succeed = true;
                    }
                }
            }
        }
        
        //update gui
        ContentMain.instance.addNewTable(getListServer());
    }

        
    public List<TodoItem> getListServer() throws RemoteException{
        return server.getList(client);
    }
    
    public void disconnect() throws RemoteException{
        server.disconnect(client);
    }
    
    public void deleteTodo(TodoItem item) throws RemoteException{
        
        int answer;
//        server.deleteTodo(item, client);
        Object[] options = { "Yes", "No" };
        answer=JOptionPane.showOptionDialog(SwingUtilities.getRoot(ContentMain.instance), 
                "Are you sure that you want to delete this item?", 
                "Confirm delete",JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
        null, options, options[0]);
        if (answer==JOptionPane.YES_OPTION) {
            boolean res = server.deleteTodo(item, client);
            if(!res){
                TodoItem newItem = server.getTodo(item.getId());
                boolean answerConflictDelete = (new ConfirmDeleteItem(newItem,(JFrame) SwingUtilities.getRoot(ContentMain.instance), true)).showDialog();
                if(answerConflictDelete)
                    server.deleteTodo(newItem, client);
            }else{
                StatusBar.instance.setStatusInfo("Delete success");
            }
        }
        
        ContentMain.instance.addNewTable(getListServer());
    }
    
    private class ConfirmDeleteItem extends JDialog implements ActionListener{
        
        private JPanel panel = null;
        private JButton yesButton = null;
        private JButton noButton = null;
        private boolean answer = false;
        
        public ConfirmDeleteItem(TodoItem item,JFrame jFrame, boolean modal){
            super(jFrame, modal);
            setSize(300, 300);
            setTitle("Item modify");
            panel = new JPanel(new BorderLayout());
            getContentPane().add(panel);
            panel.add(new DisplayPanel(item, 2),BorderLayout.CENTER);
            
            JPanel bottom = new JPanel();
            yesButton = new JButton("Yes");
            yesButton.addActionListener(this);
            bottom.add(yesButton); 
            noButton = new JButton("No");
            noButton.addActionListener(this);
            bottom.add(noButton); 
            panel.add(bottom,BorderLayout.SOUTH);
            
            setLocationRelativeTo(jFrame);
        }
        public boolean showDialog(){
            setVisible(true);
            return answer;
        }

        public void actionPerformed(ActionEvent e) {
            if(yesButton == e.getSource()) {
                answer = true;
                setVisible(false);
            }
            else if(noButton == e.getSource()) {
                answer = false;
                setVisible(false);
            }
        }
    }

}
